// ALEventSink.cpp: implementation of the CALEventSink class.
//
//////////////////////////////////////////////////////////////////////

#include "ALEventSink.h"
#include "COM_WMI_Consumer.h"
#include <comutil.h>
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/date_time/c_local_time_adjustor.hpp"
#include <wbemtime.h>
extern CB inst;

using namespace std;
using namespace boost::posix_time;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

//***************************************************************************
//
//***************************************************************************

/*STDMETHODIMP CALEventSink::QueryInterface(REFIID riid, LPVOID * ppv)
{
    *ppv = 0;

    if (IID_IUnknown==riid || IID_IWbemObjectSink == riid)
    {
        *ppv = (IWbemObjectSink *) this;
        AddRef();
        return NOERROR;
    }

    return E_NOINTERFACE;
}*/


//***************************************************************************
//
//***************************************************************************

/*ULONG CALEventSink::AddRef()
{
    return ++m_cRef;
}

//***************************************************************************
//
//***************************************************************************

ULONG CALEventSink::Release()
{
    if (0 != --m_cRef)
        return m_cRef;

    delete this;
    return 0;
}*/
ULONG CALEventSink::AddRef()
{
    return InterlockedIncrement(&m_lRef);
}

ULONG CALEventSink::Release()
{
    LONG lRef = InterlockedDecrement(&m_lRef);
    if(lRef == 0)
        delete this;
    return lRef;
}
//***************************************************************************
//
//***************************************************************************

/*HRESULT CALEventSink::Indicate(
    long lObjectCount,
    IWbemClassObject __RPC_FAR *__RPC_FAR *ppObjArray
    )
{
    // Get the info from the object.
    // =============================
	
    for (long i = 0; i < lObjectCount; i++)
    {
		// This is a collection of instances
        IWbemClassObject *pObj = ppObjArray[i];

		// Get the name of the class for this instance
		CComVariant var;
		pObj->Get(CComBSTR("ProcessID"),0,&var,0,0);
		CComVariant typevar;
		pObj->Get(CComBSTR("__CLASS"),0,&typevar,0,0);

		
		if(CComBSTR("Win32_ProcessStartTrace")==typevar.bstrVal)
			inst._Start((long)var.intVal);
		else if(CComBSTR("Win32_ProcessStopTrace")==typevar.bstrVal)
			inst._Stop((long)var.intVal);		
		else  // we don't know about this type
			return WBEM_E_FAILED;       
		
    }
    return WBEM_NO_ERROR;
}*/

HRESULT CALEventSink::QueryInterface(REFIID riid, void** ppv)
{
    if (riid == IID_IUnknown || riid == IID_IWbemObjectSink)
    {
        *ppv = (IWbemObjectSink *) this;
        AddRef();
        return WBEM_S_NO_ERROR;
    }
    else return E_NOINTERFACE;
}


HRESULT CALEventSink::Indicate(long lObjectCount,
    IWbemClassObject **apObjArray)
{
   HRESULT hr = S_OK;
   _variant_t vtProcessID;
   _variant_t vtClass;

   long ProcessID;

    for (int i = 0; i < lObjectCount; i++)
    {
    hr = apObjArray[i]->Get(_bstr_t(L"ProcessID"), 0, &vtProcessID, 0, 0);
     if (!FAILED(hr))
     {
       if ((vtProcessID.vt==VT_NULL) || (vtProcessID.vt==VT_EMPTY))
       wcout << "ProcessID : " << ((vtProcessID.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
       else
       if ((vtProcessID.vt & VT_ARRAY))
       wcout << "ProcessID : " << "Array types not supported (yet)" << endl;
       else{
      /* wcout << "ProcessID uint : " << vtProp.uintVal << endl;
	   wcout << "ProcessID int : " << vtProp.intVal << endl;*/
	   ProcessID=vtProcessID.intVal;
	   }

	   hr = apObjArray[i]->Get(_bstr_t(L"__CLASS"), 0, &vtClass, 0, 0);
 if (!FAILED(hr))
     {
		 if ((vtClass.vt==VT_NULL) || (vtClass.vt==VT_EMPTY))
       wcout << "ProcessID : " << ((vtClass.vt==VT_NULL) ? "NULL" : "EMPTY") << endl;
       else
       if ((vtClass.vt & VT_ARRAY))
       wcout << "ProcessID : " << "Array types not supported (yet)" << endl;
       else
	   {
		   if(CComBSTR("Win32_ProcessStartTrace")==vtClass.bstrVal)
			   inst._Start(ProcessID);
		   if(CComBSTR("Win32_ProcessStopTrace")==vtClass.bstrVal)
			   inst._Stop(ProcessID);
			
	   }
 }
     }
     VariantClear(&vtProcessID);
	 VariantClear(&vtClass);
		
    }

    return WBEM_S_NO_ERROR;
}

HRESULT CALEventSink::SetStatus(
            /* [in] */ LONG lFlags,
            /* [in] */ HRESULT hResult,
            /* [in] */ BSTR strParam,
            /* [in] */ IWbemClassObject __RPC_FAR *pObjParam
        )
{
    if(lFlags == WBEM_STATUS_COMPLETE)
    {
        printf("Call complete. hResult = 0x%X\n", hResult);
    }
    else if(lFlags == WBEM_STATUS_PROGRESS)
    {
        printf("Call in progress.\n");
    }

    return WBEM_S_NO_ERROR;
}    // end of EventSink.cpp
//***************************************************************************
//
//***************************************************************************

//HRESULT CALEventSink::SetStatus(
    /* [in] */ //long lFlags,
    /* [in] */ //HRESULT hResult,
    /* [in] */ //BSTR strParam,
    /* [in] */ //IWbemClassObject __RPC_FAR *pObjParam
   // )
//{
    // Not called during event delivery.
        
 //   return WBEM_NO_ERROR;
//}
